E-commerce Website Interface


The enhanced features provided by Spread.Views can be used to create a comprehensive e-commerce website design layout. The optimized user interface of Spread.Views is supported in large screen devices as well as mobile and tablet views.

You can create this demo using the following Spread.Views features:

Use the following steps to create an interface for the e-commerce website using Spread.Views, as shown in the following image.

ecommgrid

Sample Code

  1. Add the following CSS and JS references to the project.
    <link rel="stylesheet" type="text/css" href="[Your Stylesheet Path]/gc.spread.views.dataview.10.1.1.css">
    <link rel="stylesheet" type="text/css" href="[Your Stylesheet Path]/bootstrap-snippet.min.css">
    <link rel="stylesheet" type="text/css" href="[Your Stylesheet Path]/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="[Your Stylesheet Path]/gc.spread.views.cardlayout.10.1.1.css" />
    <script src="[Your Script Path]/gc.spread.common.10.1.1.min.js" type="text/javascript"></script>
    <script src="[Your Script Path]/gc.spread.views.dataview.10.1.1.min.js" type="text/javascript"></script>
    <script src="[Your Script Path]/lodash.min.js" type="text/javascript"></script>
    <script src="[Your Script Path]/gc.spread.views.cardlayout.10.1.1.min.js" type="text/javascript"></script>
    <script src="[Your Script Path]/zepto.min.js" type="text/javascript"></script>
    <script src="[Your Script Path]/license.js" type="text/javascript"></script>
       <script src="data/TVData.js" type="text/javascript"></script>
  2. Add a style tag within the head tag to apply styling to the interface.

     * {
                -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
            }
    
            ::-webkit-scrollbar {
                width: 5px;
                height: 5px;
            }
    
            ::-webkit-scrollbar-thumb {
                background: #e0e0e0;
                border-radius: 5px;
            }
    
            label {
                font-weight: normal;
                margin: 0;
            }
    
            .card-layout.gc-grid {
                border: none;
            }
    
            .card-layout .gc-row {
                text-align: center;
                padding: 3px;
            }
    
            #grid1 {
                position: absolute;
                left: 220px;
                right: 0;
                height: 100%;
            }
    
            .demo-container {
                -moz-user-select: none;
                -khtml-user-select: none;
                -webkit-user-select: none;
                -ms-user-select: none;
                user-select: none;
                width: 100%;
                height: 100%;
                position: relative;
            }
    
            .filter-panel {
                float: left;
                width: 219px;
                height: 100%;
                overflow: auto;
                display: block;
                border: none;
                z-index: auto;
                position: static;
            }
    
            .filter-header {
                color: #999;
                font-size: 17px;
                padding-bottom: 10px;
                padding-top: 6px;
            }
    
            .filter-details {
                font-size: 14px;
                font-weight: 700;
                padding-bottom: 3px;
            }
    
            .stars-box {
                display: inline-block;
                height: 13px;
                width: 65px;
                overflow: hidden;
                background-image: url("./images/star-ratings.png");
                vertical-align: middle;
            }
    
            .stars-0 {
                background-position: -65px 0;
            }
    
            .stars-0-5 {
                background-position: -52px -19px;
            }
    
            .stars-1 {
                background-position: -52px 0;
            }
    
            .stars-1-5 {
                background-position: -39px -19px;
            }
    
            .stars-2 {
                background-position: -39px 0;
            }
    
            .stars-2-5 {
                background-position: -26px -19px;
            }
    
            .stars-3 {
                background-position: -26px 0;
            }
    
            .stars-3-5 {
                background-position: -13px -19px;
            }
    
            .stars-4 {
                background-position: -13px 0;
            }
    
            .stars-4-5 {
                background-position: 0 -18px;
            }
    
            .stars-5 {
                background-position: 0 0;
            }
    
            .tv-image {
                margin-left: 10px;
            }
    
            .tv-brand {
                font-size: 13px;
                color: lightgrey;
                margin-bottom: 8px;
            }
    
            .tv-price {
                color: #b12704;
            }
    
            .mobile-filter-entry {
                display: none;
            }
    
            .filter-condition {
                display: inline-block;
                border: 1px solid lightgrey;
                width: 100px;
                height: 25px;
                font-family: -apple-system-font, "Helvetica Neue", 'Segoe UI', Helvetica, Arial, sans-serif;
                font-size: 16px;
                text-align: center;
                cursor: pointer;
            }
    
            .slicer {
                margin: 10px 0;
            }
    
            .slicer-item {
                margin: 2px 0;
                cursor: pointer;
            }
    
            .hover {
                color: #E47911;
            }
    
            .filtered {
                background-color: #FFFFFF;
            }
    
            .filteredOutByOther {
                color: #A6A8B1;
            }
    
            .filteredOutBySelf {
                background-color: #FFFFFF;
            }
    
            @media only screen and (max-width: 768px) {
                #grid1 {
                    position: static;
                    height: 90%;
                }
                .filter-panel {
                    margin-top: -1px;
                    border: 1px solid lightgrey;
                    width: 100%;
                    overflow: auto;
                    height: 90%;
                    position: absolute;
                    z-index: 1;
                    background: white;
                    padding: 5px 0 0 10px;
                    display: none;
                }
                .mobile-filter-entry {
                    height: 25px;
                    display: block;
                }
        }
  3. Add a div tag within the body tag to include the DOM element as the container in the page.

    <div class="demo-container">
            <div class="mobile-filter-entry">
                <div class="filter-condition"><span style="padding-right:5px;">Filter</span><span class="fa fa-angle-down"></span></div>
            </div>
            <div class="filter-panel">
                <div class="filter-header">Refine by</div>
                <div id="tv_display_size" class="slicer"></div>
                <div id="tv_resolution" class="slicer"></div>
                <div id="customer_review_star" class="slicer"></div>
            </div>
            <div id="grid1"></div>
        </div>
        <script type="text/javascript">
            var slicerComponentNS = GC.Spread.Slicers;
            var rowTemplate =
                '<div>' +
                '<div data-column="image"></div>' +
                '<div data-column="description"></div>' +
                '<div data-column="brand"></div>' +
                '<div data-column="price"></div>' +
                '<div data-column="starsIcon"></div>' +
                '</div>';
    
            var imagePresenter = '<img class="tv-image" src={{=it.image}} />';
            var descriptionPresenter = '<a href="#"><b>{{=it.description}}</b></a>';
            var brandPresenter = '<div class="tv-brand"><label>by {{=it.brand}}</label></div>';
            var pricePresenter = '<div>${{=it.price}}</div>';
        var startPresenter = '<div class="stars-box {{=it.starsIcon}}"></div>';
  4. Add a variable definition to instantiate the instance of Spread.Views.

    var dataView;
    var rowTemplate =
        '<div>' +
        '<div data-column="image"></div>' +
        '<div data-column="description"></div>' +
        '<div data-column="brand"></div>' +
        '<div data-column="price"></div>' +
        '<div data-column="starsIcon"></div>' +
        '</div>';
    
    var imagePresenter = '<img class="tv-image" src={{=it.image}} />';
    var descriptionPresenter = '<a href="#"><b>{{=it.description}}</b></a>';
    var brandPresenter = '<div class="tv-brand"><label>by {{=it.brand}}</label></div>';
    var pricePresenter = '<div>${{=it.price}}</div>';
    var startPresenter = '<div class="stars-box {{=it.starsIcon}}"></div>';
  5. Add a column definition to specify the grid values.
     var columns = [{
                id: 'image',
                caption: 'Image',
                dataField: 'image',
                presenter: imagePresenter
            }, {
                id: 'description',
                caption: 'Description',
                dataField: 'description',
                presenter: descriptionPresenter
            }, {
                id: 'brand',
                caption: 'Brand',
                dataField: 'brand',
                presenter: brandPresenter
            }, {
                id: 'price',
                caption: 'Price',
                dataField: 'price',
                presenter: pricePresenter
            }, {
                id: 'starsIcon',
                caption: 'StarsIcon',
                dataField: 'starsIcon',
                presenter: startPresenter
            }, {
                id: 'size',
                caption: 'TV Display Size',
                dataField: 'size'
            }, {
                id: 'refreshRate',
                caption: 'RefreshRate',
                dataField: 'refreshRate'
            }, {
                id: 'resolution',
                caption: 'Television Resolution',
                dataField: 'resolution'
            }, {
                id: 'starsValue',
                caption: 'Avg. Customer Review',
                dataField: 'starsValue'
        }];
  6. Initialize the code by calling the grid ID from the DIV tag.
     var dataView = new GC.Spread.Views.DataView(document.getElementById('grid1'), data, columns, new GC.Spread.Views.Plugins.CardLayout({
                cardHeight: 300,
                cardWidth: 210,
                rowTemplate: rowTemplate
        }));
  7. Specify functions for the filtering conditions.

    var SlicerBase = (function() {
                var SlicerBase = function(container, slicerData, columnName) {
                    var self = this;
                    self.container = container;
                    self.slicerData = slicerData;
                    self.columnName = columnName;
                    self.exclusiveDatas = slicerData.getExclusiveData(columnName);
                    self.slicerData.attachListener(self);
                    self.onDataLoaded();
                }
    
                SlicerBase.prototype = {
                    onDataLoaded: function() {
                        var self = this;
                        var container = self.container;
                        var renderedHTML = self.getRenderedHTML();
                        container.append(renderedHTML);
    
                        container.find('.slicer-item input[type=checkbox]').on('click', function(e) {
                            e.preventDefault();
                        });
                        container.find('.slicer-item').on('mouseenter', function(e) {
                            $(this).addClass("hover");
                        }).on('mouseleave', function(e) {
                            $(this).removeClass("hover");
                        }).on('mousedown', {
                            slicer: this
                        }, function(e) {
                            var slicer = e.data.slicer;
                            var slicerItem = $(e.currentTarget);
                            var targetInput = slicerItem.find('input[type=checkbox]');
                            if (targetInput) {
                                targetInput.prop('checked', !targetInput.prop('checked'));
                            }
                            var condition = slicer.getFilterCondition(e, slicer);
                            if (!condition) {
                                slicer.slicerData.doUnfilter(slicer.columnName);
                            } else {
                                slicer.slicerData.doFilter(slicer.columnName, condition);
                            }
                        });
                    },
                    onFiltered: function(args) {
                        clearSlicerItemClass.call(this);
                        this.updateSlicerItem();
                        var newData = _.map(args.rowIndexes, function(index) {
                            return data[index];
                        });
                        dataView.data.setSource_(newData); //Need to be replaced
                        dataView.invalidate();
                    }
                };
    
                function clearSlicerItemClass() {
                    var items = this.container.find('.slicer-item');
                    var classes = ['filtered', 'filteredOutByOther'];
                    _.each(items, function(item) {
                        _.each(classes, function(itemClass) {
                            $(item).removeClass(itemClass);
                        });
                    });
                }
    
                return SlicerBase;
            })();
    
            var ResolutionFilter = (function(super_) {
                var ResolutionFilter = function(container, slicerData, columnName) {
                    super_.call(this, container, slicerData, columnName);
                }
                extends_(ResolutionFilter, super_);
    
                ResolutionFilter.prototype.getRenderedHTML = function() {
                    var self = this;
                    var columnName = self.columnName;
                    var datas = self.exclusiveDatas;
                    var slicerData = self.slicerData;
    
                    var header = '<div class="filter-details">' + getCaption(columnName) + '</div>';
                    var body = '';
                    for (var i = 0, length = datas.length; i < length; i++) {
                        var count = slicerData.getRowIndexes(columnName, i).length;
                        body += '<div class="slicer-item"><input type="checkbox" /><span>' + datas[i] + '</span><span style="color:#A29999">(' + count + ')</span></div>';
                    }
                    return header + body;
                };
    
                ResolutionFilter.prototype.getFilterCondition = function(e, slicer) {
                    var container = slicer.container;
                    var inputs = container.find('input[type=checkbox]');
                    var indexes = [];
                    _.each(inputs, function(item, i) {
                        if (item.checked) {
                            indexes.push(i);
                        }
                    });
                    return indexes.length ? {
                        exclusiveRowIndexes: indexes
                    } : null;
                };
    
                ResolutionFilter.prototype.updateSlicerItem = function() {
                    var self = this;
                    var items = this.container.find('.slicer-item');
                    var i;
                    var length;
                    var filteredItems = self.slicerData.getFilteredIndexes(self.columnName);
                    for (i = 0, length = filteredItems.length; i < length; i++) {
                        $(items[filteredItems[i]]).addClass("filtered");
                    }
                    var filteredOutByOtherItems = self.slicerData.getFilteredOutIndexes(self.columnName, slicerComponentNS.FilteredOutDataType.byOtherColumns);
                    for (i = 0, length = filteredOutByOtherItems.length; i < length; i++) {
                        $(items[filteredOutByOtherItems[i]]).addClass("filteredOutByOther");
                    }
                };
    
                return ResolutionFilter;
            })(SlicerBase);
    
            var DisplaySizeFilter = (function(super_) {
                var DisplaySizeFilter = function(container, slicerData, columnName) {
                    this.rangeInfo = [{
                        range: {
                            min: -Infinity,
                            max: 32
                        },
                        label: '32 Inches & Under'
                    }, {
                        range: {
                            min: 33,
                            max: 43
                        },
                        label: '33 to 43 Inches'
                    }, {
                        range: {
                            min: 44,
                            max: 49
                        },
                        label: '44 to 49 Inches'
                    }, {
                        range: {
                            min: 50,
                            max: 59
                        },
                        label: '50 to 59 Inches'
                    }, {
                        range: {
                            min: 60,
                            max: 69
                        },
                        label: '60 to 69 Inches'
                    }, {
                        range: {
                            min: 70,
                            max: Infinity
                        },
                        label: '70 Inches & Up'
                    }];
                    super_.call(this, container, slicerData, columnName);
                };
                extends_(DisplaySizeFilter, super_);
    
                DisplaySizeFilter.prototype.getRenderedHTML = function() {
                    var self = this;
                    var columnName = self.columnName;
                    var slicerData = self.slicerData;
    
                    var header = '<div class="filter-details">' + getCaption(columnName) + '</div>';
                    var body = '';
                    var info = self.rangeInfo;
                    for (var i = 0, length = info.length; i < length; i++) {
                        var count = slicerData.getData(columnName, info[i].range).length;
                        body += '<div class="slicer-item"><input type="checkbox" /><span>' + info[i].label + '</span><span style="color:#A29999">(' + count + ')</span></div>';
                    }
                    return header + body;
                };
    
                DisplaySizeFilter.prototype.getFilterCondition = function(e, slicer) {
                    var container = slicer.container;
                    var inputs = container.find('input[type=checkbox]');
                    var ranges = [];
                    _.each(inputs, function(item, i) {
                        if (item.checked) {
                            ranges.push(slicer.rangeInfo[i].range);
                        }
                    });
                    return ranges.length ? {
                        ranges: ranges
                    } : null;
                };
    
                DisplaySizeFilter.prototype.updateSlicerItem = function() {
                    var self = this;
                    var i;
                    var length;
                    var j;
                    var len;
                    var filteredItems = self.slicerData.getFilteredIndexes(self.columnName);
                    var filteredOutByOtherItems = self.slicerData.getFilteredOutIndexes(self.columnName, slicerComponentNS.FilteredOutDataType.byOtherColumns);
                    var items = this.container.find('.slicer-item');
                    var slicerData = self.slicerData;
                    var columnIndex = slicerData.getColumnIndex(self.columnName);
                    for (j = 0, len = items.length; j < len; j++) {
                        var range = self.rangeInfo[j].range;
                        for (i = 0, length = filteredItems.length; i < length; i++) {
                            if (range.min <= slicerData.data[filteredItems[i]][columnIndex] && slicerData.data[filteredItems[i]][columnIndex] <= range.max) {
                                $(items[j]).addClass("filtered");
                            }
                        }
                        for (i = 0, length = filteredOutByOtherItems.length; i < length; i++) {
                            if (range.min <= slicerData.data[filteredOutByOtherItems[i]][columnIndex] && slicerData.data[filteredOutByOtherItems[i]][columnIndex] <= range.max) {
                                $(items[j]).addClass("filteredOutByOther");
                            }
                        }
                    }
                };
    
                return DisplaySizeFilter;
            })(SlicerBase);
    
            var CustomerReviewFilter = (function(super_) {
                var CustomerReviewFilter = function(container, slicerData, columnName) {
                    this.rangeInfo = [{
                        range: {
                            min: 4,
                            max: Infinity
                        },
                        label: '<span class="stars-box stars-4"></span><span>&Up</span>'
                    }, {
                        range: {
                            min: 3,
                            max: Infinity
                        },
                        label: '<span class="stars-box stars-3"></span><span>&Up</span>'
                    }, {
                        range: {
                            min: 2,
                            max: Infinity
                        },
                        label: '<span class="stars-box stars-2"></span><span>&Up</span>'
                    }, {
                        range: {
                            min: 1,
                            max: Infinity
                        },
                        label: '<span class="stars-box stars-1"></span><span>&Up</span>'
                    }];
                    super_.call(this, container, slicerData, columnName);
                }
                extends_(CustomerReviewFilter, super_);
    
                CustomerReviewFilter.prototype.getRenderedHTML = function() {
                    var self = this;
                    var columnName = self.columnName;
                    var slicerData = self.slicerData;
    
                    var header = '<div class="filter-details">' + getCaption(columnName) + '</div>';
                    var body = '';
                    var info = self.rangeInfo;
                    for (var i = 0, length = info.length; i < length; i++) {
                        var count = slicerData.getData(columnName, info[i].range).length;
                        body += '<div data-index=' + i + ' class="slicer-item">' + info[i].label + '<span style="color:#A29999">(' + count + ')</span></div>';
                    }
                    return header + body;
                };
    
                CustomerReviewFilter.prototype.getFilterCondition = function(e, slicer) {
                    var currentTarget = e.currentTarget;
                    var index = $(currentTarget).data('index');
                    return {
                        ranges: [slicer.rangeInfo[index].range]
                    };
                };
    
                CustomerReviewFilter.prototype.updateSlicerItem = function() {
                    var self = this;
                    var i;
                    var length;
                    var j;
                    var len;
                    var filteredItems = self.slicerData.getFilteredIndexes(self.columnName);
                    var filteredOutByOtherItems = self.slicerData.getFilteredOutIndexes(self.columnName, slicerComponentNS.FilteredOutDataType.byOtherColumns);
                    var items = this.container.find('.slicer-item');
                    var slicerData = self.slicerData;
                    var columnIndex = slicerData.getColumnIndex(self.columnName);
                    for (j = 0, len = items.length; j < len; j++) {
                        var range = self.rangeInfo[j].range;
                        for (i = 0, length = filteredItems.length; i < length; i++) {
                            if (range.min <= slicerData.data[filteredItems[i]][columnIndex] && slicerData.data[filteredItems[i]][columnIndex] <= range.max) {
                                $(items[j]).addClass("filtered");
                            }
                        }
                        for (i = 0, length = filteredOutByOtherItems.length; i < length; i++) {
                            if (range.min <= slicerData.data[filteredOutByOtherItems[i]][columnIndex] && slicerData.data[filteredOutByOtherItems[i]][columnIndex] <= range.max) {
                                $(items[j]).addClass("filteredOutByOther");
                            }
                        }
                    }
                };
    
                return CustomerReviewFilter;
            })(SlicerBase);
    
            function getCaption(id) {
                var column = _.find(columns, function(col) {
                    return col.id === id;
                });
                return column.caption;
            }
    
            function extends_(d, b) {
                for (var p in b) {
                    if (b.hasOwnProperty(p)) {
                        d[p] = b[p];
                    }
                }
    
                function __() {
                    this.constructor = d;
                }
    
                __.prototype = b.prototype;
                d.prototype = new __();
            }
    
            var dataNames = _.keys(data[0]);
            var dataArr = [];
            _.forEach(data, function(item) {
                dataArr.push(_.values(item));
            });
            var dataSource = new slicerComponentNS.GeneralSlicerData(dataArr, dataNames);
            var TVDisplaySizeFilter = new DisplaySizeFilter($('#tv_display_size'), dataSource, 'size');
            var TVResolutionFilter = new ResolutionFilter($('#tv_resolution'), dataSource, 'resolution');
        var CustomerReviewFilter = new CustomerReviewFilter($("#customer_review_star"), dataSource, "starsValue");